package com.mosaic.girih;

import java.util.Random;
import android.graphics.Bitmap;

public class MosaicFilter {

	protected String name;
	protected int height;
	protected int width;
	protected int nbFilters;
	protected int[][] filters;

	public void setName(String n) {
		name = n;
	}

	public String getName() {
		return name;
	}

	public void setHeight(int h) {
		height = h;
	}

	public int getHeight() {
		return height;
	}

	public void setWidth(int w) {
		width = w;
	}

	public int getWidth() {
		return width;
	}

	public void setNbFilters(int n) {
		nbFilters = n;
	}

	public int getNbFilters() {
		return nbFilters;
	}

	public void setFilter(String n, int h, int w, int nb, int[][] f) {
		setName(n);
		setHeight(h);
		setWidth(w);
		setNbFilters(nb);
		filters = new int[nbFilters][height * width];
		for (int j = 0; j < nbFilters; j++) {
			for (int i = 0; i < height * width; i++) {
				filters[j][i] = f[j][i];
			}
		}
	}

	public MosaicFilter() {
		int[][] f = { { 1 } };
		setFilter("noname", 1, 1, 1, f);
	}

	public Bitmap applyMosaic(Bitmap inBitmap) {
		int outWidth = inBitmap.getWidth() - (inBitmap.getWidth() % width);
		int outHeight = inBitmap.getHeight() - (inBitmap.getHeight() % height);
		Bitmap outBitmap = Bitmap.createBitmap(outWidth, outHeight,
				Bitmap.Config.ARGB_8888);

		// Initialize randomization
		Random randomGen = new Random();

		// Apply mosaic
		for (int yb = 0; yb < outHeight / height; yb++) {
			for (int xb = 0; xb < outWidth / width; xb++) {
				// Allocate pixel buffers
				int inPixels[] = new int[height * width];
				int outPixels[] = new int[height * width];

				// Initialize input buffer
				inBitmap.getPixels(inPixels, 0, width, xb * width, yb * height,
						width, height);

				// Do the average colors on the source image for the
				// corresponding mosaic square
				int r_avg = 0;
				int g_avg = 0;
				int b_avg = 0;
				int avg = 0;

				for (int y = 0; y < height; y++) {
					for (int x = 0; x < width; x++) {
						int index = x + y * width;

						// Retrieve color values of the source image
						r_avg += inPixels[index] >> 16 & 0xff;
						g_avg += inPixels[index] >> 8 & 0xff;
						b_avg += inPixels[index] & 0xff;
					}
				}

				// Make average of R,G and B on filter size
				r_avg = r_avg / (width * height);
				g_avg = g_avg / (width * height);
				b_avg = b_avg / (width * height);

				// Record average in one pixel value
				avg = 0xff000000 | (r_avg << 16) | (g_avg << 8) | b_avg;

				int type = randomGen.nextInt(nbFilters); // Select a kind of
															// filter
				// Apply mosaic
				for (int y = 0; y < height; y++) {
					for (int x = 0; x < width; x++) {
						int index = x + y * width;

						int tmpValFilter = filters[type][y * width + x];
						outPixels[index] = tmpValFilter & avg;
					}
				}

				// Write in output bitmap
				outBitmap.setPixels(outPixels, 0, width, xb * width, yb
						* height, width, height);
			}
		}

		return outBitmap;
	}

}